<?php

namespace app\controller\backend;

use app\model\DiyForm;
use Overtrue\Pinyin\Pinyin;
use think\facade\Db;

class FormController extends BaseController
{
    public function index(DiyForm $diyFormModel)
    {
        $limit = input('param.limit');
        $name = input('param.name');

        $where[] = ['is_del', '=', 1];
        $where[] = ['seller_id', '=', $this->admin['seller_id']];
        if (!empty($name)) {
            $where[] = ['name', 'like', '%' . $name . '%'];
        }

        try {

            $list = $diyFormModel->where($where)->order('id desc')->paginate($limit);
        } catch (\Exception $e) {
            return jsonReturn(-1, $e->getMessage());
        }

        return json(pageReturn(dataReturn(0, lang('成功'), $list)));
    }

    public function info(DiyForm $diyFormModel)
    {
        $id = $this->request->param('id');

        $info = $diyFormModel->where('id', $id)->find();
        if (empty($info)) {
            return jsonReturn(-3, lang('该表单不存在'));
        }

        return jsonReturn(0, lang('获取成功'), $info);
    }

    public function add(DiyForm $diyFormModel)
    {
        $param = input('post.');

        if (empty($param['name'])) {
            return jsonReturn(-1, lang('请输入表单名称'));
        }

        try {

            $has = $diyFormModel->where('name', $param['name'])->find();
            if (!empty($has)) {
                return jsonReturn(-3, lang('该表单已经存在'));
            }

            $pinyinModel = new Pinyin();
            $tableName = $pinyinModel->abbr($param['name']);
            $has = $diyFormModel->where('table', $tableName)->find();
            if (!empty($has)) {
                $tableName = $tableName . '_' . uniqid();
            }

            $param['seller_id'] = $this->admin['seller_id'];
            $param['table'] = $tableName;
            $param['code'] = uniqid(); // 表单唯一标识
            $param['create_time'] = date('Y-m-d H:i:s');

            $diyFormModel->insert($param);
        } catch (\Exception $e) {
            return jsonReturn(-4, $e->getMessage());
        }

        return jsonReturn(0, lang('添加成功'));
    }

    public function edit(DiyForm $diyFormModel)
    {
        $param = input('post.');

        if (empty($param['name'])) {
            return jsonReturn(-1, lang('请输入表单名称'));
        }

        try {

            $has = $diyFormModel->where('name', $param['name'])->where('id', '<>', $param['id'])->find();
            if (!empty($has)) {
                return jsonReturn(-3, lang('该表单已经存在'));
            }

            $pinyinModel = new Pinyin();
            $tableName = $pinyinModel->abbr($param['name']);
            $has = $diyFormModel->where('table', $tableName)->where('id', '<>', $param['id'])->find();
            if (!empty($has)) {
                $tableName = $tableName . '_' . uniqid();
            }

            $param['table'] = $tableName;
            $param['update_time'] = date('Y-m-d H:i:s');
            $diyFormModel->where('id', $param['id'])->update($param);
        } catch (\Exception $e) {
            return jsonReturn(-4, $e->getMessage());
        }

        return jsonReturn(0, lang('编辑成功'));
    }

    public function del(DiyForm $diyFormModel)
    {
        $id = input('param.id');
        try {
            $info = $diyFormModel->where('id', $id)->find();
            if ($info['status'] == 2) {
                return jsonReturn(-1,  lang('该表单已经发布，请先卸载'));
            }

            $diyFormModel->where('id', $id)->delete();
        } catch (\Exception $e) {
            return jsonReturn(-2, $e->getMessage());
        }

        return jsonReturn(0, lang('删除成功'));
    }

    public function detail(DiyForm $diyFormModel)
    {
        $param = input('param.');
        try {

            $info = $diyFormModel->where('id', $param['id'])->find();
            $formJson = json_decode($info['design_content'], true);

            $field2Dict = [];
            $header = [];

            foreach ($formJson as $vo) {
                if (!isset($vo['field'])) {
                    continue;
                }

                $header[] = [
                    'label' => $vo['title'],
                    'property' => $vo['field'],
                    'type' => $vo['type'],
                    'options' => $vo['options'] ?? ''
                ];

                // 为了方便字典翻译，优化前端显示
                if (isset($vo['options'])) {

                    $dictDataMap = [];
                    foreach ($vo['options'] as $k => $v) {
                        $dictDataMap[$v['value']] = $v['label'];
                    }

                    $field2Dict[$vo['field']] = $dictDataMap;
                }

                if ($vo['type'] == 'switch') {
                    $dictDataMap = [];
                    $dictDataMap[$vo['props']['activeValue']] = $vo['props']['activeText'];
                    $dictDataMap[$vo['props']['inactiveValue']] = $vo['props']['inactiveText'];
                    $field2Dict[$vo['field']] = $dictDataMap;
                }

            }

            $param['queryParams'] = json_decode($param['queryParams'], true);

            if (!empty($param['queryParams']) &&
                !empty($param['queryParams']['condition']) &&
                !empty($param['queryParams']['childTips'])) {

                $where = $this->buildWhere($param['queryParams']['childTips']);
                if ($param['queryParams']['condition'] == 'and') {


                    $data = Db::table(makeFormTable($info['table']))->where($where)
                        ->order('id', 'desc')->paginate($param['limit']);
                } else if ($param['queryParams']['condition'] == 'or') {

                    $data = Db::table(makeFormTable($info['table']))->whereOr($where)
                        ->order('id', 'desc')->paginate($param['limit']);
                }

            } else {

                $data = Db::table(makeFormTable($info['table']))
                    ->order('id', 'desc')->paginate($param['limit']);
            }

            $data = $data->each(function ($item) use ($field2Dict) {

                foreach ($item as $key => $vo) {

                    if (isset($field2Dict[$key])) {

                        $showValueMap = [];
                        $valueMap = explode(',', $vo);

                        foreach ($valueMap as $valueKey) {
                            $showValueMap[] = isset($field2Dict[$key][$valueKey]) ? $field2Dict[$key][$valueKey] : $valueKey;
                        }

                        $item[$key] = implode(',', $showValueMap);
                    }
                }

                return $item;
            });

        } catch (\Exception $e) {
            return jsonReturn(-3, $e->getMessage() . $e->getLine());
        }

        return jsonReturn(0, 'success', [
            'header' => $header,
            'data' => $data->getCollection(),
            'total' => $data->total()
        ]);
    }

    public function deploy(DiyForm $diyFormModel)
    {
        $id = input('param.id');
        $info = $diyFormModel->where('id', $id)->find();

        if ($info['status'] == 2) {
            return jsonReturn(-1, lang('该表单已经发布，无需再次发布'));
        }

        if (empty($info['design_content'])) {
            return jsonReturn(-2, lang('请先完成表单设计'));
        }

        $tableName = makeFormTable($info['table']);
        $title = $info['name'];

        $column = '';
        $columnMap = json_decode($info['design_content'], true);
        foreach ($columnMap as $key => $vo) {

            if (empty($vo['field'])) {
                continue;
            }

            // 强迫症为了dd打印的时候格式对其，其实没啥意义
            $tab = '';
            if ($key > 0) {
                $tab = '    ';
            }

            $column .= $tab . '`' . $vo['field'] . '` varchar(255) NULL DEFAULT NULL COMMENT "' . $vo['title'] . '",' . PHP_EOL;
        }

        try {

            $sql = <<<EOL
CREATE TABLE `{$tableName}` (
    `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT "id",
    {$column}    `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT "创建时间",
    `update_time` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT "更新时间",
    `visitor_id` varchar(255) DEFAULT '' COMMENT '前端标识',
    `sub_id` int(11) DEFAULT 0 COMMENT '关联内容id',
    `ip` varchar(20) DEFAULT '',
    `user_agent` varchar(255) DEFAULT '' COMMENT '浏览器标识',
     PRIMARY KEY (`id`) 
)ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 COMMENT='{$title}';
EOL;
            Db::execute($sql);

            $diyFormModel->where('id', $id)->update([
                'status' => 2,
                'update_time' => date('Y-m-d H:i:s')
            ]);
        } catch (\Exception $e) {
            return jsonReturn(-4, $e->getMessage());
        }

        return jsonReturn(0, lang('部署成功'));
    }

    public function undeploy(DiyForm $diyFormModel)
    {
        $id = input('param.id');

        $info = $diyFormModel->where('id', $id)->find();
        if ($info['status'] != 2) {
            return jsonReturn(-1, lang('该表单尚未发布，无法卸载'));
        }

        try {

            Db::query('DROP TABLE IF EXISTS `' . makeFormTable($info['table']) . '`');
            $diyFormModel->where('id', $id)->update([
                'status' => 1,
                'update_time' => date('Y-m-d H:i:s')
            ]);
        } catch (\Exception $e) {
            return jsonReturn(-1, $e->getMessage());
        }

        return jsonReturn(0, lang('卸载成功'));
    }

    // 获取问题和答案详情
    public function quesDetail(DiyForm $diyFormModel)
    {
        $param = input('param.');
        try {

            $info = $diyFormModel->where('id', $param['id'])->find();
            $formJson = json_decode($info['design_content'], true);

            $field2Dict = [];
            $header = [];

            foreach ($formJson as $vo) {
                if (!isset($vo['field'])) {
                    continue;
                }

                $header[$vo['field']] = [
                    'label' => $vo['title'],
                    'property' => $vo['field'],
                    'type' => $vo['type'],
                    'options' => []
                ];

                if ($vo['type'] == 'switch') {
                    $header[$vo['field']]['options'][$vo['props']['activeValue']] = ['label' => $vo['props']['activeText']];
                    $header[$vo['field']]['options'][$vo['props']['inactiveValue']] = ['label' => $vo['props']['inactiveText']];
                }

                if (!empty($vo['options'])) {
                    foreach ($vo['options'] as $v) {
                        $header[$vo['field']]['options'][$v['value']] = $v;
                    }
                }
            }

            $param['queryParams'] = json_decode($param['queryParams'], true);

            if (!empty($param['queryParams']) &&
                !empty($param['queryParams']['condition']) &&
                !empty($param['queryParams']['childTips'])) {

                $where = $this->buildWhere($param['queryParams']['childTips']);

                if ($param['queryParams']['condition'] == 'and') {

                    $data = Db::table(makeFormTable($info['table']))->where($where)->select();

                } else if ($param['queryParams']['condition'] == 'or') {

                    $data = Db::table(makeFormTable($info['table']))->whereOr($where)->select();
                } else {
                    $data = [];
                }
            } else {
                $data = Db::table(makeFormTable($info['table']))->select();
            }


            $newData = [];
            $quesNum = 1;
            foreach ($header as $key => $value) {
                foreach ($data as $item) {
                    if (!isset($item[$key])) {
                        continue;
                    }

                    $newData[$key]['quesNum'] = $quesNum;
                    $newData[$key]['type'] = $value['type'];
                    $newData[$key]['ques'] = $value['label'];

                    if (!isset($newData[$key]['total'])) {
                        $newData[$key]['total'] = 0;
                    }
                    if ($value['type'] == 'input' || $value['type'] == 'timePicker' || $value['type'] == 'datePicker') {
                        $newData[$key]['type_name'] = '填空';
                        $newData[$key]['type'] = 'list';
                        // 填空题 ，填的才是答案，使用列表展示
                        $newData[$key]['total']++;

                        $newData[$key]['detail'][] = [
                            'id' => $item['id'],
                            'answer' => $item[$key],
                        ];
                    } else if ($value['type'] == 'radio' || $value['type'] == 'select' || $value['type'] == 'switch') {
                        $newData[$key]['type_name'] = '单选';
                        $newData[$key]['type'] = 'radio';
                        // 单选题 使用饼图展示，需要计算百分比
                        $newData[$key]['total']++;

                        if (isset($newData[$key]['detail'][$item[$key]]['count'])) {
                            $newData[$key]['detail'][$item[$key]]['count']++;
                        } else {
                            $newData[$key]['detail'][$item[$key]]['answer'] = $value['options'][$item[$key]]['label'];
                            $newData[$key]['detail'][$item[$key]]['count'] = 1;
                        }
                    } else if ($value['type'] == 'slider' || $value['type'] == 'rate'){
                        $newData[$key]['type_name'] = '滑块/打分';
                        $newData[$key]['type'] = 'rate';
                        $newData[$key]['total']++;
                        if (isset($newData[$key]['detail'][$item[$key]]['count'])) {
                            $newData[$key]['detail'][$item[$key]]['count']++;
                        } else {
                            $newData[$key]['detail'][$item[$key]]['answer'] = $item[$key];
                            $newData[$key]['detail'][$item[$key]]['count'] = 1;
                        }
                    }
                    else if ($value['type'] == 'checkbox') {
                        $newData[$key]['type_name'] = '多选';
                        // 多选题 默认使用柱状图，需要计算百分比
                        $answer = explode(',', $item[$key]);
                        foreach ($answer as $v) {
                            $newData[$key]['total']++;

                            if (isset($newData[$key]['detail'][$v]['count'])) {
                                $newData[$key]['detail'][$v]['count']++;
                            } else {
                                $newData[$key]['detail'][$v]['answer'] = $value['options'][$v]['label'];
                                $newData[$key]['detail'][$v]['count'] = 1;
                            }
                        }
                    }
                }
                $quesNum++;
            }

            // 整理成前端echart需要的数据
            foreach ($newData as &$value) {
                if ($value['type'] == 'list') {
                    continue;
                }
                $newDetail = [];
                foreach ($value['detail'] as $v) {
                    $newDetail['data'][] = [
                        'name' => $v['answer'],
                        'value' => $v['count'],
                    ];
                    $newDetail['nameArr'][] = $v['answer'];
                    $newDetail['valueArr'][] = $v['count'];
                }
                $value['detail'] = $newDetail;
            }

//            dd($newData);

        } catch (\Exception $e) {
            return jsonReturn(-3, $e->getMessage() . $e->getLine());
        }

        return jsonReturn(0, lang('成功'), [
            'header' => array_values($header),
            'data' => $newData,
            'total' => count($newData),
        ]);
    }

    private function buildWhere($childTips)
    {
        $where = [];

        foreach ($childTips as $vo) {

            switch ($vo['rule']) {

                case 'eq':
                    $where[] = [$vo['field'], '=', $vo['val']];
                    break;
                case 'like':
                    $where[] = [$vo['field'], 'like', '%' . $vo['val'] . '%'];
                    break;
                case 'left_like':
                    $where[] = [$vo['field'], 'like', '%' . $vo['val']];
                    break;
                case 'right_like':
                    $where[] = [$vo['field'], 'like', $vo['val'] . '%'];
                    break;
                case 'neq':
                    $where[] = [$vo['field'], '<>', $vo['val']];
                    break;
                case 'gt':
                    $where[] = [$vo['field'], '>', $vo['val']];
                    break;
                case 'gte':
                    $where[] = [$vo['field'], '>=', $vo['val']];
                    break;
                    break;
                case 'lt':
                    $where[] = [$vo['field'], '<', $vo['val']];
                    break;
                case 'lte':
                    $where[] = [$vo['field'], '<=', $vo['val']];
                    break;
            }
        }

        return $where;
    }
}
